package com.hube.platform.tenant.aop;

import com.hube.platform.tenant.configuration.DynamicDataSource;
import com.hube.platform.tenant.constant.AppConstant;
import com.hube.platform.tenant.entity.po.TenantDataBaseConfigPO;
import com.hube.platform.tenant.helper.ApplicationContextHelper;
import com.hube.platform.tenant.helper.DynamicDataSourceContextHolder;
import com.hube.platform.tenant.helper.FacadeBuilder;
import com.hube.platform.tenant.service.TenantInfoService;
import com.zaxxer.hikari.HikariConfig;
import ma.glasnost.orika.MapperFacade;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
@Order(1) // 请注意：这里order一定要小于tx:annotation-driven的order，即先执行DynamicDataSourceAspectAdvice切面，再执行事务切面，才能获取到最终的数据源
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class DynamicDataSourceAspect {

    @Autowired
    private TenantInfoService tenantInfoService;

    private static final Logger log = LoggerFactory.getLogger(DynamicDataSourceAspect.class);

    //bean拷贝工具类
    private static final MapperFacade facade = FacadeBuilder.mapperFactory.getMapperFacade();


    @Pointcut("@annotation(com.hube.platform.tenant.annotation.AutoSwitchDB)")
    public void autoSwitchDB() {
    }

    @Around("autoSwitchDB()")
    public Object doAround(ProceedingJoinPoint jp) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String tenantId = request.getHeader("tenantId");
        log.info("----current tenant id----:{}", tenantId);
        if (StringUtils.isBlank(tenantId)) {
            tenantId = AppConstant.MASTER_DB;
        }
        //判断当前数据源时候包括
        if (!DynamicDataSourceContextHolder.containDataSourceKey(tenantId)) {
            //读取配置
            TenantDataBaseConfigPO tenantConfig = tenantInfoService.getTenantInfoById(tenantId);
            DynamicDataSource dynamicDataSource = (DynamicDataSource) ApplicationContextHelper.getBean(AppConstant.DYNAMIC_DATA_SOURCE);
            dynamicDataSource.addDataSource(tenantId, tenantConfig.getDatabaseName(), facade.map(tenantConfig, HikariConfig.class));
        }
        //根据租户ID切换数据源
        DynamicDataSourceContextHolder.setDataSourceKey(tenantId);
        Object result = jp.proceed();
        //清除当前数据源
        DynamicDataSourceContextHolder.clearCurrentDataSourceKey();
        return result;
    }
}